"""
全新的交易系统实现，不依赖auto_stable_01.py
"""
import logging
from datetime import datetime
from typing import Dict, List, Optional

logger = logging.getLogger(__name__)


class StableTradingV3:
    """
    全新的交易系统实现类
    """
    
    def __init__(self, db_config: Dict):
        """
        初始化交易系统
        :param db_config: 数据库配置字典
        """
        self.db_config = db_config
        self.trade_system = TradeSystem(db_config)
        
        # 交易配置
        self.stop_loss_ratio = 0.05  # 固定止损比例
        self.trailing_stop_ratio = 0.03  # 追踪止损比例
        self.use_fixed_stop_loss = True  # 默认使用固定止损
        
        # 初始化API连接
        self.api = self._init_trading_api()
        
    def _init_trading_api(self):
        """初始化交易API"""
        from tqsdk import TqApi, TqAuth
        try:
            # 从db_config读取天勤账户配置
            self.api = TqApi(auth=TqAuth(self.db_config['tq_username'], self.db_config['tq_password']))
            logger.info("交易API初始化成功")
            return self.api
        except Exception as e:
            logger.error(f"交易API初始化失败: {str(e)}")
            raise
        
    def stop_loss(self, symbol: str, price: float) -> bool:
        """
        止损逻辑
        :param symbol: 交易品种
        :param price: 当前价格
        :return: 是否执行了止损操作
        """
        if self.use_fixed_stop_loss:
            return self._fixed_stop_loss(symbol, price)
        else:
            return self._moving_stop_loss(symbol, price)
            
    def _fixed_stop_loss(self, symbol: str, price: float) -> bool:
        """限额止损实现"""
        positions = self.get_positions(symbol)
        for pos in positions:
            if pos['direction'] == 'long' and price <= pos['price'] * (1 - self.stop_loss_ratio):
                return self.close_position(pos['position_id'], price)
            elif pos['direction'] == 'short' and price >= pos['price'] * (1 + self.stop_loss_ratio):
                return self.close_position(pos['position_id'], price)
        return False
        
    def _moving_stop_loss(self, symbol: str, price: float) -> bool:
        """均线追踪止损实现"""
        klines = self.get_klines(symbol)
        ma = self._calculate_moving_average(klines)
        
        positions = self.get_positions(symbol)
        for pos in positions:
            if pos['direction'] == 'long' and price <= ma * (1 - self.trailing_stop_ratio):
                return self.close_position(pos['position_id'], price)
            elif pos['direction'] == 'short' and price >= ma * (1 + self.trailing_stop_ratio):
                return self.close_position(pos['position_id'], price)
        return False
        
    def open_position(self, symbol: str, direction: str) -> bool:
        """
        开仓逻辑
        :param symbol: 交易品种
        :param direction: 方向 (long/short)
        :return: 是否成功开仓
        """
        if not self._check_position_and_orders(symbol, direction):
            return False
            
        price = self.get_current_price(symbol)
        volume = self._calculate_open_volume(symbol, direction, price)
        
        if self._is_shfe_symbol(symbol):
            return self._open_shfe_position(symbol, direction, price, volume)
        else:
            return self._open_normal_position(symbol, direction, price, volume)
            
    def _check_position_and_orders(self, symbol: str, direction: str) -> bool:
        """检查持仓和未完成订单"""
        # 实现检查逻辑
        return True
        
    def _calculate_open_volume(self, symbol: str, direction: str, price: float) -> int:
        """计算开仓手数"""
        margin = self.get_product_margin(symbol)
        available = self.get_available_funds()
        target_volume = int((available * 0.2) / (price * margin))
        return max(1, target_volume)
        
    def get_positions(self, symbol: str) -> List[Dict]:
        """获取持仓信息"""
        return self.trade_system.get_user_positions(symbol)
        
    def get_orders(self, symbol: str, status: str = None) -> List[Dict]:
        """获取订单信息"""
        return self.trade_system.get_user_orders(symbol, status)
        
    def close_position(self, position_id: str, price: float) -> bool:
        """平仓"""
        try:
            position = self.trade_system.get_position_by_id(position_id)
            if not position:
                return False
                
            direction = 'sell' if position['direction'] == 'long' else 'buy'
            order = self.api.insert_order(
                symbol=position['symbol'],
                direction=direction,
                offset='close',
                volume=position['volume'],
                limit_price=price
            )
            
            # 记录平仓订单
            self.trade_system.create_order({
                'order_id': order.order_id,
                'symbol': position['symbol'],
                'direction': direction,
                'price': price,
                'volume': position['volume'],
                'status': 'pending',
                'create_time': datetime.now()
            })
            return True
        except Exception as e:
            logger.error(f"平仓失败: {str(e)}")
            return False
        
    def get_current_price(self, symbol: str) -> float:
        """获取当前价格"""
        try:
            quote = self.api.get_quote(symbol)
            return (quote.ask_price1 + quote.bid_price1) / 2
        except Exception as e:
            logger.error(f"获取{symbol}价格失败: {str(e)}")
            return 0.0
        
    def get_klines(self, symbol: str, duration_seconds=60, count=200) -> List[Dict]:
        """获取K线数据"""
        try:
            klines = self.api.get_kline_serial(symbol, duration_seconds, count)
            return [{
                'open': k.open,
                'high': k.high,
                'low': k.low,
                'close': k.close,
                'datetime': k.datetime
            } for k in klines]
        except Exception as e:
            logger.error(f"获取{symbol}K线失败: {str(e)}")
            return []
        
    def _calculate_moving_average(self, klines: List[Dict], period=20) -> float:
        """计算移动平均线"""
        if len(klines) < period:
            return 0.0
        closes = [k['close'] for k in klines[-period:]]
        return sum(closes) / period
        
    def _is_shfe_symbol(self, symbol: str) -> bool:
        """判断是否为上海交易所品种"""
        return symbol.startswith('SHFE.')
        
    def _open_shfe_position(self, symbol: str, direction: str, price: float, volume: int) -> bool:
        """上海交易所品种开仓"""
        try:
            # SHFE品种限价单价格计算
            limit_price = price * 1.01 if direction == 'long' else price * 0.99
            
            order = self.api.insert_order(
                symbol=symbol,
                direction=direction,
                offset='open',
                volume=volume,
                limit_price=limit_price
            )
            
            # 记录开仓订单
            self.trade_system.create_order({
                'order_id': order.order_id,
                'symbol': symbol,
                'direction': direction,
                'price': limit_price,
                'volume': volume,
                'status': 'pending',
                'create_time': datetime.now()
            })
            
            # 监控订单状态
            return self._monitor_order(order.order_id, symbol, direction, volume)
        except Exception as e:
            logger.error(f"SHFE品种{symbol}开{direction}仓失败: {str(e)}")
            return False
        
    def _open_normal_position(self, symbol: str, direction: str, price: float, volume: int) -> bool:
        """非SHFE品种开仓"""
        try:
            # 非SHFE品种使用对手价
            order = self.api.insert_order(
                symbol=symbol,
                direction=direction,
                offset='open',
                volume=volume,
                order_price_type='opponent'
            )
            
            # 记录开仓订单
            self.trade_system.create_order({
                'order_id': order.order_id,
                'symbol': symbol,
                'direction': direction,
                'price': price,
                'volume': volume,
                'status': 'pending',
                'create_time': datetime.now()
            })
            
            # 监控订单状态
            return self._monitor_order(order.order_id, symbol, direction, volume)
        except Exception as e:
            logger.error(f"非SHFE品种{symbol}开{direction}仓失败: {str(e)}")
            return False
            
    def _monitor_order(self, order_id: str, symbol: str, direction: str, volume: int) -> bool:
        """监控订单状态"""
        try:
            # 30秒超时监控
            timeout = 30
            start_time = datetime.now()
            
            while (datetime.now() - start_time).seconds < timeout:
                order = self.api.get_order(order_id)
                
                if order.status == 'FINISHED':
                    # 记录成交
                    self.trade_system.record_trade({
                        'trade_id': f"{order_id}_{datetime.now().timestamp()}",
                        'order_id': order_id,
                        'symbol': symbol,
                        'direction': direction,
                        'price': order.trade_price,
                        'volume': volume,
                        'trade_time': datetime.now()
                    })
                    return True
                elif order.status == 'ALIVE':
                    self.api.wait_update()
                else:
                    logger.error(f"订单{order_id}状态异常: {order.status}")
                    return False
            
            logger.error(f"订单{order_id}监控超时")
            return False
        except Exception as e:
            logger.error(f"监控订单{order_id}失败: {str(e)}")
            return False
        
    def get_product_margin(self, symbol: str) -> float:
        """获取产品保证金"""
        try:
            with self.trade_system.get_connection() as conn:
                cursor = conn.cursor()
                cursor.execute("SELECT margin FROM products WHERE symbol=%s", (symbol,))
                result = cursor.fetchone()
                return result[0] if result else 0.0
        except Exception as e:
            logger.error(f"查询{symbol}保证金失败: {str(e)}")
            return 0.0
        
    def get_available_funds(self) -> float:
        """获取可用资金"""
        try:
            account = self.api.get_account()
            return account.available
        except Exception as e:
            logger.error(f"获取可用资金失败: {str(e)}")
            return 0.0


class TradeSystem:
    """
    交易系统核心类
    """
    
    def __init__(self, db_config: Dict):
        """初始化数据库连接"""
        import mysql.connector
        from mysql.connector import pooling
        
        self.db_config = db_config
        self.pool = pooling.MySQLConnectionPool(
            pool_name="trading_pool",
            pool_size=5,
            host="172.28.196.123",
            port=3306,
            user="remote_admin",
            password="Admin@szlwy68",
            database="trade_monitor"
        )
    
    def get_connection(self):
        """获取数据库连接"""
        return self.pool.get_connection()
        
    def get_user_positions(self, symbol: str) -> List[Dict]:
        """获取用户持仓"""
        try:
            with self.get_connection() as conn:
                cursor = conn.cursor(dictionary=True)
                cursor.execute(
                    """
                    SELECT * FROM positions 
                    WHERE symbol=%s AND volume > 0
                    """, (symbol,)
                )
                return cursor.fetchall()
        except Exception as e:
            logger.error(f"查询{symbol}持仓失败: {str(e)}")
            return []
        
    def get_position_by_id(self, position_id: str) -> Optional[Dict]:
        """根据ID获取持仓"""
        try:
            with self.get_connection() as conn:
                cursor = conn.cursor(dictionary=True)
                cursor.execute("SELECT * FROM positions WHERE position_id=%s", (position_id,))
                return cursor.fetchone()
        except Exception as e:
            logger.error(f"查询持仓{position_id}失败: {str(e)}")
            return None
        
    def get_user_orders(self, symbol: str, status: str = None) -> List[Dict]:
        """获取用户订单"""
        try:
            with self.get_connection() as conn:
                cursor = conn.cursor(dictionary=True)
                if status:
                    cursor.execute(
                        "SELECT * FROM trade_orders WHERE symbol=%s AND status=%s",
                        (symbol, status)
                    )
                else:
                    cursor.execute(
                        "SELECT * FROM trade_orders WHERE symbol=%s",
                        (symbol,)
                    )
                return cursor.fetchall()
        except Exception as e:
            logger.error(f"查询{symbol}订单失败: {str(e)}")
            return []
            
    def create_order(self, order_data: Dict) -> bool:
        """创建订单记录"""
        try:
            with self.get_connection() as conn:
                cursor = conn.cursor()
                cursor.execute(
                    """
                    INSERT INTO trade_orders (
                        order_id, symbol, direction, price, 
                        volume, status, create_time
                    ) VALUES (%s, %s, %s, %s, %s, %s, %s)
                    """,
                    (
                        order_data['order_id'],
                        order_data['symbol'],
                        order_data['direction'],
                        order_data['price'],
                        order_data['volume'],
                        order_data['status'],
                        order_data['create_time']
                    )
                )
                conn.commit()
                return True
        except Exception as e:
            logger.error(f"创建订单失败: {str(e)}")
            return False


def main():
    """主函数"""
    import json
    
    # 从db_config.json读取配置
    with open('db_config.json', 'r', encoding='utf-8') as f:
        db_config = json.load(f)
    
    trading_system = StableTradingV3(db_config)
    
    # 示例使用
    trading_system.open_position('SHFE.RU2401', 'long')
    trading_system.stop_loss('SHFE.RU2401', 15000)


if __name__ == '__main__':
    main()